package ar.com.gals.repository;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import ar.com.gals.domain.Gals;


public class AbstractRepository<T> {

	protected Class<T> domain;
	
	protected Session session;
	
	
	public AbstractRepository(Session session, Class<T> domain) {
		this.session = session;
		this.domain = domain;
	}
	
	
	@SuppressWarnings("unchecked")
	public T getById(int id) {
		Criteria criteria = this.session.createCriteria(domain)
				.add(Restrictions.idEq(id))
				.add(Restrictions.isNull("fechaDelete"))
				.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		List<T> list = (List<T>) criteria.list();
		if(list.isEmpty()) return null;
		return (T) list.get(0);
	}
	
	
	@SuppressWarnings("unchecked")
	public List<T> getAll() {
		Criteria criteria = this.session.createCriteria(domain)
				.add(Restrictions.isNull("fechaDelete"))
				.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		List<T> list = (List<T>) criteria.list();
		return list;
	}
	
	
	@SuppressWarnings("unchecked")
	public List<T> getAllOrderBy(String property) {
		Criteria criteria = this.session.createCriteria(domain)
				.add(Restrictions.isNull("fechaDelete"))
				.addOrder(Order.asc(property))
				.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		List<T> list = (List<T>) criteria.list();
		return list;
	}
	
	
	@SuppressWarnings("unchecked")
	public List<T> getAllLimit(int limit) {
		Criteria criteria = this.session.createCriteria(domain)
				.add(Restrictions.isNull("fechaDelete"))
				.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
				.setMaxResults(limit);
		List<T> list = (List<T>) criteria.list();
		return list;
	}

	
	@SuppressWarnings("unchecked")
	public List<T> getAllOrderByLimit(String property, int limit) {
		Criteria criteria = this.session.createCriteria(domain)
				.add(Restrictions.isNull("fechaDelete"))
				.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
				.addOrder(Order.asc(property))
				.setMaxResults(limit);
		List<T> list = (List<T>) criteria.list();
		return list;
	}
	
	
	public void create(T t) {
		Gals object = (Gals) t;
		object.setFechaInsert(new Date());
		object.setVersion(0);
		this.session.persist(object);
	}
	
	
	public void update(T t) {
		Gals object = (Gals) t;
		object.setFechaUpdate(new Date());
		object.setVersion(object.getVersion()+1);
		this.session.merge(object);
	}
	
	
	public void delete(T t) {
		Gals object = (Gals) t;
		object.setFechaDelete(new Date());
		this.session.merge(object);
	}
}
